package com.aws.demo.utils;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

/**
 * @author lzz
 * @create 2021-09-06 9:52
 */
public class S3Sample {
    private static String bucketName = "testbucket";

    private static  final String nextLine = "\r\n";
    private static  final String towHyphens = "--";
    private static  final String boudary = "********";

    public static void upload(String uploadnFileName, String keyName) {
        AWSCredentials credentials = new BasicAWSCredentials("minioadmin", "minioadmin");
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setSignerOverride("AWSS3V4SignerType");

        AmazonS3 s3Client = AmazonS3ClientBuilder
                .standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:9000", Regions.US_EAST_1.name()))
                .withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfiguration)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
        System.out.println("Uploading a new object to S3 from a file\n");
        File file = new File(uploadnFileName);
        // 上传文件
        s3Client.putObject(new PutObjectRequest(bucketName, keyName, file));
    }


    public static void download(String keyName) throws IOException {
        AWSCredentials credentials = new BasicAWSCredentials("minioadmin", "minioadmin");
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setSignerOverride("AWSS3V4SignerType");

        AmazonS3 s3Client = AmazonS3ClientBuilder
                .standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:9000", Regions.US_EAST_1.name()))
                .withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfiguration)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
        // 下载文件
        GetObjectRequest rangeObjectRequest = new GetObjectRequest(bucketName, keyName);
        S3Object objectPortion = s3Client.getObject(rangeObjectRequest);
        System.out.println("Printing bytes retrieved:");
        displayTextInputStream(objectPortion.getObjectContent());
    }

    private static void displayTextInputStream(InputStream input) throws IOException {
        // 按行读取并打印。
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null) {
                break;
            }

            System.out.println("    " + line);
        }

    }

    /**
     * 获取预签名url
     *
     * @return
     */
    public static URL getPreSignString(String bucketName, String key) {

        AWSCredentials credentials = new BasicAWSCredentials("minioadmin1", "minioadmin1");
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setSignerOverride("AWSS3V4SignerType");

        AmazonS3 s3Client = AmazonS3ClientBuilder
                .standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration("http://localhost:9000", Regions.US_EAST_1.name()))
                .withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfiguration)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .build();
        return s3Client.generatePresignedUrl(bucketName, key, new Date());
    }

    /**
     * 通过预签名连接上传
     * @param preSignStr
     * @param filePath
     */
    public static void uploadByPreSignStr(URL preSignStr, String filePath) {
        DataOutputStream dataOutputStream = null;
        try {
            URL url = new URL(preSignStr.toString());
            URLConnection urlConnection = url.openConnection();
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            httpURLConnection.setDoInput(true);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestMethod("PUT");
            httpURLConnection.setRequestProperty("Connection","Keep-Alive");
            httpURLConnection.setRequestProperty("Charset","UTF-8");
            httpURLConnection.setRequestProperty("Content-Type","multipart/form-data;boundary="+boudary);
            dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
            String filename = filePath.substring(filePath.lastIndexOf("//") + 2);


            String header = towHyphens + boudary + nextLine;
            header += "Content-Disposition: form-data;name=\"file\";" + "filename=\"" + filename + nextLine + nextLine;
            dataOutputStream.write(header.getBytes());

            // 上传本地文件
            FileInputStream fileInputStream = new FileInputStream(filePath);
            byte[] buffer = new byte[1024];
            int len = -1;
            int flag = 0;
            while ((len=fileInputStream.read(buffer)) != -1) {
                dataOutputStream.write(buffer, 0, len);
                flag++;
            }
            String footer = nextLine + towHyphens + boudary + towHyphens + nextLine;
            dataOutputStream.write(footer.getBytes());
            dataOutputStream.flush();
            int responseCode = httpURLConnection.getResponseCode();
            String responseMessage = httpURLConnection.getResponseMessage();
            System.out.println(responseCode + " : " + responseMessage);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (dataOutputStream != null) {
                try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        URL preSignString = getPreSignString(bucketName, "testPre.jpg");
        uploadByPreSignStr(preSignString,"D://test.jpg");
//        upload("D:\\test.txt","test1.txt");
//        download("test.txt");


    }
}
